using System; 
using System.Collections.Generic;

public abstract class Expression {
    public abstract double Evaluate(Dictionary<string, object> vars);
}

public class Constant : Expression {
    double _value;
    public Constant(double value) {
        _value = value;
    }
    public override double Evaluate(Dictionary<string, object> vars) {
        return _value;
    }
 }

public class VariableReference : Expression {
    string _name;
    public VariableReference(string name) {
        this._name = name;
    }
    public override double Evaluate(Dictionary<string, object> vars) {
        object value = vars[_name] ?? throw new Exception($"Unknown variable {_name}");
        return Convert.ToDouble(value);
    }
}

public class Operation : Expression {
    Expression _left;
    char _op;
    Expression _right;
    public Operation(Expression left, char op, Expression right) {
        this._left = left;
        this._op = op;
        this._right = right;
    }
    public override double Evaluate(Dictionary<string, object> vars) {
        double x = _left.Evaluate(vars);
        double y = _right.Evaluate(vars);
        switch(_op) {
            case '+' : return x+y;
            case '-': return x- y;
            case '*':return x * y;
            case '/':return x/y;
            default:throw new Exception("Unknown operator");
        }
    }
}